package com.nakanomay.redis7.service;

import com.nakanomay.redis7.entities.Customer;
import com.nakanomay.redis7.mapper.CustomerMapper;
import com.nakanomay.redis7.utils.CheckUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author nakano_may丶
 * @create 2023/5/5
 * @Version 1.0
 * @description
 */
@Service
@Slf4j
public class CustomerService
{
    public static final String CACHE_KEY_CUSTOMER = "customer:";

    @Resource private CustomerMapper customerMapper;
    @Resource private RedisTemplate redisTemplate;

    /**
     * 写操作
     *
     * @param customer
     */
    public void addCustomer(Customer customer)
    {
        int i = customerMapper.insertSelective(customer);

        if (i > 0)
        {
            // mysql插入成功，需要重新查询一次数据捞出来，写进redis
            customer = customerMapper.selectByPrimaryKey(customer.getId());
            // redis缓存key
            String key = CACHE_KEY_CUSTOMER + customer.getId();
            // 捞出来的数据写进redis
            redisTemplate.opsForValue().set(key, customer);
        }
    }

    /**
     * 读操作
     *
     * @param customerId
     * @return
     */
    public Customer findCustomerById(Integer customerId)
    {
        Customer customer = null;
        // 缓存redis的key名称
        String key = CACHE_KEY_CUSTOMER + customerId;
        // 1 先去redis查询
        customer = (Customer) redisTemplate.opsForValue().get(key);

        // 2 redis中有直接返回，没有再去查询mysql
        if (customer == null)
        {
            // 3 再去查询mysql
            customer = customerMapper.selectByPrimaryKey(customerId);
            // 3.1 mysql有，redis无
            if (customer != null)
            {
                // 3.2 把mysql查询到的数据写回到redis中，保持一致性
                redisTemplate.opsForValue().set(key, customer);
            }
        }
        return customer;
    }

    /**
     * BloomFilter → redis → mysql
     * 白名单：whitelistCustomer
     *
     * @param customerId
     * @return
     */

    @Resource
    private CheckUtils checkUtils;

    public Customer findCustomerByIdWithBloomFilter(Integer customerId)
    {
        Customer customer = null;

        //缓存key的名称
        String key = CACHE_KEY_CUSTOMER + customerId;

        //布隆过滤器check，无是绝对无，有是可能有
        //===============================================
        if (!checkUtils.checkWithBloomFilter("whitelistCustomer", key))
        {
            log.info("白名单无此顾客信息:{}", key);
            return null;
        }
        //===============================================

        //1 查询redis
        customer = (Customer) redisTemplate.opsForValue().get(key);
        //redis无，进一步查询mysql
        if (customer == null)
        {
            //2 从mysql查出来customer
            customer = customerMapper.selectByPrimaryKey(customerId);
            // mysql有，redis无
            if (customer != null)
            {
                //3 把mysql捞到的数据写入redis，方便下次查询能redis命中。
                redisTemplate.opsForValue().set(key, customer);
            }
        }
        return customer;
    }
}
